package com.pig4cloud.pigx.strategy.websocket.app.manager;

import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.customize.enums.AbnormalEnum;
import com.pig4cloud.pigx.strategy.websocket.app.dto.WebSocketMessageDTO;
import com.pig4cloud.pigx.strategy.websocket.app.message.SendMessage;
import com.pig4cloud.pigx.strategy.websocket.app.message.SubscribeMessage;
import com.pig4cloud.pigx.strategy.websocket.app.message.UnSubscribeMessage;
import com.pig4cloud.pigx.strategy.websocket.app.subscribe.StrategyContractCurrentDetail;
import com.pig4cloud.pigx.strategy.websocket.app.subscribe.StrategyContractList;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 */
@Slf4j
@Component
@AllArgsConstructor
public class WsManager {

    @Autowired
    private StrategyContractCurrentDetail strategyContractCurrentDetail;
    @Autowired
    private StrategyContractList strategyContractList;

    public Map<WebSocketSession, Long> webSocketSessionMap = new ConcurrentHashMap<>();

    private WsManager() {
        init();
    }

    public void init() {
        check();
    }

    public void subscribe(WebSocketSession session, SubscribeMessage subscribeMessage) {
        if (webSocketSessionMap.get(session) == null) {
            webSocketSessionMap.put(session, System.currentTimeMillis());
        }
        WebSocketMessageDTO params = subscribeMessage.getParams();
        // 请求api为空返回异常信息
        if (params.getRequestApi() == null || params.getRequestApi().isEmpty()) {
            try {
                session.sendMessage(SendMessage.getTextMessage(R.failed(
                        AbnormalEnum.MSG.MANDATORY_PARAM_EMPTY_OR_MALFORMED.getCode(),
                        AbnormalEnum.MSG.MANDATORY_PARAM_EMPTY_OR_MALFORMED.getMessage()
                )));
            } catch (IOException e) {
                e.printStackTrace();
                log.error("webSocket消息发送异常");
            }
        }
        switch (params.getRequestApi()) {
            case StrategyContractCurrentDetail.API_NAME:
                strategyContractCurrentDetail.sub(session, params);
                break;
            case StrategyContractList.API_NAME:
                strategyContractList.sub(session, params);
                break;
            default:
                break;
        }
    }

    public void unsubscribe(WebSocketSession session, UnSubscribeMessage unsubscribeMessage) {
        WebSocketMessageDTO params = unsubscribeMessage.getParams();
        // 请求api为空返回异常信息
        if (params.getRequestApi() != null && !params.getRequestApi().isEmpty()) {
            switch (params.getRequestApi()) {
                case StrategyContractCurrentDetail.API_NAME:
                    strategyContractCurrentDetail.unSub(session);
                    break;
                case StrategyContractList.API_NAME:
                    strategyContractList.unSub(session);
                    break;
                default:
                    break;
            }
        }
    }

    private void check() {
        ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
        service.scheduleAtFixedRate(() -> {
            try {
                webSocketSessionMap.forEach((k, v) -> {
                    if (!k.isOpen()) {
                        webSocketSessionMap.remove(k);
                    }
                });
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }, 10, 50, TimeUnit.SECONDS);
    }

}
